package com.black.utils.config.loader;

import com.alibaba.fastjson2.JSONObject;
import com.black.utils.file.FileTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * @author ylx
 */
@Slf4j
public class XMLLoader extends Loader {

    @Override
    public JSONObject loadJsonConfig(String sourcePath) throws IOException {
        File xmlFile = new File(sourcePath);
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(xmlFile);
            Element root = document.getDocumentElement();
            JSONObject config = new JSONObject();
            config.put("version", document.getXmlVersion());
            config.put("encoding", document.getXmlEncoding());
            config.put(root.getNodeName(), toJson(root));
            return config;
        } catch (ParserConfigurationException | SAXException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    @Override
    public List<FileTypeEnum> getTypes() {
        return Collections.singletonList(FileTypeEnum.XML);
    }

    private JSONObject toJson(Node node) {
        JSONObject item = new JSONObject();
        if (node.hasAttributes()) {
            NamedNodeMap attributes = node.getAttributes();
            JSONObject attrs = new JSONObject();
            for (int i = 0; i < attributes.getLength(); i++) {
                Node attribute = attributes.item(i);
                attrs.put(attribute.getNodeName(), attribute.getNodeValue());
            }
            item.put("attrs", attrs);
        }
        if (node.hasChildNodes()) {
            NodeList childNodes = node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node childNode = childNodes.item(i);
                short nodeType = childNode.getNodeType();
                switch (nodeType) {
                    case Node.ELEMENT_NODE:
                        item.put(childNode.getNodeName(), toJson(childNode));
                        break;
                    case Node.ATTRIBUTE_NODE:
                    case Node.TEXT_NODE:
                        String nodeValue = node.getNodeValue();
                        if (nodeValue != null && !nodeValue.trim().isEmpty()) {

                            //TODO implement
                        }

                    default:
                        return item;
                }
                item.put(childNode.getNodeName(), toJson(childNode));
            }
        }
        return item;
    }
}
